#ifndef QOS_CPP_TYPES
#define QOS_CPP_TYPES

#if defined(ARDUINO) || defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAMD) || defined(ENERGIA_ARCH_MSP430ELF)
    #define ARDUINO_PLATFORM
#endif

#if (__cplusplus < 201103L || defined (__AVR_ARCH__) || defined(ARDUINO_PLATFORM) || defined (STM8Sxx))
    #include <stddef.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <limits.h>
    #define STD_TYPE_UINT8_T    uint8_t
    #define STD_TYPE_UINT16_T   uint16_t
    #define STD_TYPE_UINT32_T   uint32_t
    #define STD_TYPE_UINT64_T   uint64_t
    #define STD_TYPE_INT8_T     int8_t
    #define STD_TYPE_INT16_T    int16_t
    #define STD_TYPE_INT32_T    int32_t
    #define STD_TYPE_INT64_T    int64_t
    #define STD_TYPE_UINTPTR_T  uintptr_t
    #define STD_TYPE_SIZE_T     size_t
#else
    #include <cstddef>
    #include <cstdint>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <climits>
    #define STD_TYPE_UINT8_T    std::uint8_t
    #define STD_TYPE_UINT16_T   std::uint16_t
    #define STD_TYPE_UINT32_T   std::uint32_t
    #define STD_TYPE_UINT64_T   std::uint64_t
    #define STD_TYPE_INT8_T     std::int8_t
    #define STD_TYPE_INT16_T    std::int16_t
    #define STD_TYPE_INT32_T    std::int32_t
    #define STD_TYPE_INT64_T    std::int64_t
    #define STD_TYPE_UINTPTR_T  std::uintptr_t
    #define STD_TYPE_SIZE_T     std::size_t
#endif

#if defined(ARDUINO_PLATFORM)
    #include <Arduino.h>
#else
    #include <string>
#endif

#ifndef SIZE_MAX
    #define SIZE_MAX (~static_cast<size_t>(0))
#endif

namespace qOS {
    /** @addtogroup  qtypes
    * @brief Sets of types having specified widths used to design the entire OS.
    * It also define macros directives to perform specific actions and options
    * for some OS APIs.
    * @{
    */

    /**
    * @brief A type to instantiate a integer-base variable. This size of this type is
    * implementation-defined.
    */
    using base_t = int;

    /**
    * @brief A type to instantiate a byte variable
    */
    using byte_t = STD_TYPE_UINT8_T;

    /**
    * @brief A type to instantiate an unsigned variable
    */
    using unsigned_t = unsigned long;

    /**
    * @brief A type to instantiate an signed variable
    */
    using signed_t = long int;

    /**
    * @brief A type to instantiate a single-precision variable of 32-bits IEEE 754.
    */
    using float32_t = float;   /*this is not always true in some compilers*/

    /**
    * @brief A type to instantiate a single-precision variable of 64-bits IEEE 754.
    */
    using float64_t = double;   /*this is not always true in some compilers*/

    /**
    * @brief A type to instantiate an OS index variable. Can store the maximum
    * size of a theoretically possible object of any type (including array).
    * Should be used for array indexing and loop counting.
    */
    using index_t = STD_TYPE_SIZE_T;

    /**
    * @brief A type to instantiate a variable that hold the number of task cycles.
    */
    using cycles_t = STD_TYPE_UINT32_T;

    /**
    * @brief A type to instantiate a variable that hold the number of task iterations.
    */
    using iteration_t = STD_TYPE_INT32_T;

    /**
    * @brief A type to instantiate a variable to hold the priority value of a task.
    */
    using priority_t = STD_TYPE_UINT8_T;

    /*! @cond */
    using uint8_t = STD_TYPE_UINT8_T;
    using uint16_t = STD_TYPE_UINT16_T;
    using uint32_t = STD_TYPE_UINT32_T;
    using uint64_t = STD_TYPE_UINT64_T;
    using int8_t = STD_TYPE_INT8_T;
    using int16_t = STD_TYPE_INT16_T;
    using int32_t = STD_TYPE_INT32_T;
    using int64_t = STD_TYPE_INT64_T;
    using uintptr_t = STD_TYPE_UINTPTR_T;
    using size_t = STD_TYPE_SIZE_T;
    #if defined(ARDUINO_PLATFORM)
        using string = String;
    #else
        using string = std::string;
    #endif

    class nonCopyable {
        protected:
            nonCopyable() {}
            ~nonCopyable() {}
        private:
            nonCopyable(const nonCopyable &);
            nonCopyable& operator=(const nonCopyable &);
    };

    /*! @endcond */

    /**
    * @brief A type to instantiate a variable to hold a time count.
    *
    * Linux / Unix (x86_64, AArch64), unsigned long, 64 bits
    * 32 bits system (x86、ARM 32 bits) unsigned long, 32 bits
    */
    using timeCount_t = unsigned long;

    /** @}*/
}

/*! @cond */
#define     Q_UNUSED(arg)     (void)(arg)
#define     Q_NONE            /*EMPTY MACRO*/
/*! @endcond */

#endif /*QOS_CPP_TYPES*/
